package com.tjetc.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class _3ReflectEfficiency {

    public static void main1(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        List<Integer> list = new ArrayList<>();
        list.add(1);

        // 因为泛型在底层运行时存在类型擦除 所有的泛型在底层都会成Object
        Class aClass = list.getClass();
        Method method = aClass.getMethod("add", Object.class);
        method.invoke(list, "abc");
        System.out.println(list);


    }


    // 演示反射的效率
    public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        f();
        f1();
        f2();

    }

    // new 对象
    public static void f(){
        _1Cat cat = new _1Cat();
        // 设置开始时间
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            cat.hi();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("用时：" + (endTime - startTime));
    }
    // 反射创建对象
    public static void f1() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class cls = Class.forName("com.tjetc.reflect._1Cat");
        Object o = cls.getDeclaredConstructor().newInstance();
        Method method = cls.getMethod("hi");
        // 设置开始时间
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            method.invoke(o);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("用时：" + (endTime - startTime));
    }

    // 禁止java检查 反射创建对象
    public static void f2() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class cls = Class.forName("com.tjetc.reflect._1Cat");
        Object o = cls.getDeclaredConstructor().newInstance();

        Method method = cls.getMethod("hi");
        // 禁止检查
        method.setAccessible(true);
        // 设置开始时间
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            method.invoke(o);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("用时：" + (endTime - startTime));
    }
}
